package com.itheima.common.ui;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;

/**
 * 主界面底部导航栏
 *
 */
public class TabBar extends LinearLayout {

	private String[] mTabNames;

	private int[] mTabIconsNormal;
	private int[] mTabIconsSelected;

	/** 选项卡字体和图标的颜色：普通状态 */
	private int mTabColorNormal = Color.GRAY;

	/** 选项卡字体和图标的颜色：选中状态 */
	private int mTabColorSelected = Color.WHITE;

	/** 四个选项卡 */
	private TabItem[] mTabs;

	/** 当前选中的选项卡 */
	private TabItem mCurrentTab;

	/** 选项卡图标的宽 */
	private int mIconWidth;
	/** 选项卡图标的高 */
	private int mIconHeight;

	public TabBar(Context context) {
		super(context);
		init();
	}

	private void init() {
	}

	private int dp2px(int dp) {
		return (int) (getContext().getResources().getDisplayMetrics().density * dp
				+ 0.5f);
	}

	public TabBar(Context context, @Nullable AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	/**
	 * 设置选项卡未读条数
	 * @param position 要设置的选项卡
	 * @param unreadCount
	 */
	public void setTabUnreadCount(int position, int unreadCount) {
		try {
			mTabs[position].setUnreadCount(unreadCount);
		} catch(Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 显示或隐藏选项卡上的红点（红点表示有信息更新）
	 *
	 * @param position 要设置的选项卡
	 * @param visible true为显示
	 */
	public void setRedDotVisible(int position, boolean visible) {
		try {
			mTabs[position].setRedDotVisible(visible);
		} catch(Exception e) {
			e.printStackTrace();
		}
	}

	/** 设置选项卡的透明度 */
	public void updateTabAlpha(int position, float alpha) {
		try {
			mTabs[position].updateTabAlpha(alpha);
		} catch(Exception e) {
			e.printStackTrace();
		}
	}

	public void setTabColorNormal(int tabColorNormal) {
		this.mTabColorNormal = tabColorNormal;
	}

	public void setTabColorSelected(int tabColorSelected) {
		this.mTabColorSelected = tabColorSelected;
	}

	public void setTabSelectedColor(int color) {
		setTabColorSelected(color);
		if (mCurrentTab != null) {
			for (int i = 0; i < mTabs.length; i++) {
				TabItem tab = mTabs[i];
				tab.setTabSelectedColor(color);
			}
		}
	}

	public void setTabNormalColor(int color) {
		setTabColorNormal(color);
		if (mCurrentTab != null) {
			for (int i = 0; i < mTabs.length; i++) {
				TabItem tab = mTabs[i];
				tab.setTabNormalColor(color);
			}
		}
	}

	/** 选项卡中图片与文字的垂直间距 */
	int paddingBetweenTextAndIcon = dp2px(0);

	/** 设置图标和文本之间的间距 */
	public void setPaddingBetweenTextAndIcon(int padding) {
		this.paddingBetweenTextAndIcon = padding;
		if (mTabs != null) {
			for (int i = 0; i < mTabs.length; i++) {
				mTabs[i].setPaddingBetweenTextAndIcon(paddingBetweenTextAndIcon);
			}
			invalidate();
		}
	}

	public void setIconSize(int iconWidth, int iconHeight) {
		this.mIconWidth  = iconWidth;
		this.mIconHeight = iconHeight;
		if (mTabs != null) {
			for (int i = 0; i < mTabs.length; i++) {
				mTabs[i].setIconSize(iconWidth, iconHeight);
			}
		}
	}

	/** 选项卡切换监听 */
	public interface OnTabSelectedListener {
		public void onTabSelected(int position);
	}

	private OnTabSelectedListener mOnTabSelectedListener;

	public void setOnTabSelectedListener(OnTabSelectedListener onTabSelectedListener) {
		this.mOnTabSelectedListener = onTabSelectedListener;
	}

	OnClickListener mOnTabClickListener = new OnClickListener() {
		@Override
		public void onClick(View v) {
			int position = (int) v.getTag();
			setTabSelected(position);

			// 选项卡切换了, 作回调
			if (mOnTabSelectedListener != null) {
				mOnTabSelectedListener.onTabSelected(position);
			}
		}
	};

	/**
	 * 设置选项卡显示的数据和图标
	 *
	 * @param titles 选项卡显示的文本
	 * @param iconsNormal  选项卡默认状态下显示的图标
	 * @param iconsSelected 选项卡选中状态下显示的图标
	 */
	public void setTabDatas(String[] titles, int[] iconsNormal, int[] iconsSelected) {
		this.mTabNames = titles;
		this.mTabIconsNormal = iconsNormal;
		this.mTabIconsSelected = iconsSelected;

		removeAllViews();

		mTabs = new TabItem[titles.length];
		int padding = dp2px(5);		// 5dp

		LayoutParams param = new LayoutParams(0,
				LayoutParams.MATCH_PARENT);
		param.weight = 1;		// 使用权重，表示四个选项卡会平分屏幕的宽度

		for (int i = 0; i < mTabs.length; i++) {
			TabItem tab = new TabItem(getContext());
			mTabs[i] = tab;

			// 设置选项卡的标题和图片
			int iconSelected = mTabIconsSelected != null ? mTabIconsSelected[i] : 0;
			tab.setTextAndIcon(titles[i], mTabIconsNormal[i], iconSelected);

			tab.setTabNormalColor(mTabColorNormal);
			tab.setTabSelectedColor(mTabColorSelected);

			tab.setOnClickListener(mOnTabClickListener);

			if (paddingBetweenTextAndIcon != 0)
				tab.setPaddingBetweenTextAndIcon(paddingBetweenTextAndIcon);

			if (mIconWidth != 0)
				tab.setIconSize(mIconWidth, mIconHeight);

			tab.setTag(i);
			tab.setPadding(0, padding, 0, padding);

			addView(tab, param);
		}

		// 默认选中的是第一个选项卡
		mCurrentTab = mTabs[0];
		mCurrentTab.setTabSelected(true);  		// 选中，选项卡会高亮显示
	}

	public void setTabDatas(String[] titles, int[] iconsNormal) {
		setTabDatas(titles, iconsNormal, null);
	}

	/**
	 * 选中某一个选项卡
	 *
	 * @param position 要选中的位置
	 */
	public void setTabSelected(int position) {
		System.out.println("-----------position: " + position);
		if (mTabNames != null && position >= 0 && position < mTabNames.length) {
			// 当前选中的取消高亮
			mCurrentTab.setTabSelected(false);

			// 记录新的选中的选项卡
			mCurrentTab = mTabs[position];

			// 新点击的选项卡设为高亮
			mCurrentTab.setTabSelected(true);
		}
	}

	/**
	 * 主界面底部选项卡指示器控件. <br/>
	 * （1）选项卡显示的内容需包括图标和文字内容。<br/>
	 * （2）可以传两张图片，也可以传一张图片，如果传一张图片，选中的的高亮效果会通过着色实现<br/>
	 * （3）传一张图片时，可以实现类似微信的滑动时的选项卡渐变效果<br/>
	 *
	 * @author WJQ
	 */
	public static class TabItem extends View {

		/** tab显示的文本 */
		private String mTabText = "标题";

		/** 选项卡图标: 普通状态。也可以只使用一张图标，选中时会对它进行着色 */
		private Bitmap mTabIconNormal;
		/** 选项卡图标: 选中状态。也可以只使用一张图标，选中时会对它进行着色 */
		private Bitmap mTabIconSelected;

		/** 选项卡字体和图标的颜色：普通状态 */
		private int mTabColorNormal = Color.GRAY;

		/** 选项卡字体和图标的颜色：选中状态 */
		private int mTabColorSelected = Color.WHITE;

		/** 选项卡字体大小: 默认为12sp */
		private int mTabTextSize = dp2px(12);

		/** 选项卡中图标的宽 */
		private int mIconWidth = dp2px(25);
		/** 选项卡中图标的高 */
		private int mIconHeight = dp2px(25);
		/** 选项卡中图片与文字的垂直间距 */
		int paddingBetweenTextAndIcon = dp2px(0);

		/** 滑动时图标的透明度 */
		private float mAlphaPercent;

		/** 渐变的bitmap对象 */
		private Bitmap mGradientBitmap;

		/** 绘制图标的画笔 */
		private Paint mIconPaint;
		/** 绘制文本的画笔 */
		private Paint mTextPaint = new Paint();

		/** 图标的绘制区域 */
		private Rect mIconRect = new Rect();
		/** 文字的绘制区域 */
		private Rect mTextBound = new Rect();

		public TabItem(Context context) {
			super(context);
			init();
		}

		public TabItem(Context context, AttributeSet attrs) {
			super(context, attrs);
			init();
		}

		public void init() {
			mTextPaint.setAntiAlias(true);
			mTextPaint.setTextSize(mTabTextSize);
			mTextPaint.setColor(mTabColorNormal);
			mTextPaint.getTextBounds(mTabText, 0, mTabText.length(), mTextBound);
			mRedDotPaint.setAntiAlias(true); 	// 去锯齿

			mUnreadCountPaint.setAntiAlias(true); // 去锯齿
			mUnreadCountPaint.setTextSize(mTabTextSize);
			mUnreadCountPaint.setTextAlign(Paint.Align.CENTER); // 居中显示

			getUnreadCountTextHeight();
		}

		/** 设置选项卡选中时字体和图标的颜色 */
		public void setTabSelectedColor(int color) {
			this.mTabColorSelected = color;
			invalidate();
		}

		/** 设置选项卡非选中状态下字体和图标的颜色 */
		public void setTabNormalColor(int color) {
			this.mTabColorNormal = color;
			invalidate();
		}

		/** 获取未读条数字体显示高度 */
		public void getUnreadCountTextHeight() {
			Rect unreadCountRect = new Rect();
			mUnreadCountPaint.getTextBounds("1", 0, 1, unreadCountRect);
			mUnreadCountTextHeight = unreadCountRect.height();
		}

		/**
		 * 测量控件，初始化图标的绘制区域
		 */
		@Override
		protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
			super.onMeasure(widthMeasureSpec, heightMeasureSpec);
			// 图标宽高是一样的，取两者的较小值
			initTabDrawArea();
		}

		/**
		 * 根据图片的宽高，初始化选项卡图标相对于选项卡本身的绘制区域,保存到变量mIconRect中
		 */
		private void initTabDrawArea() {
			int left = getMeasuredWidth() / 2 - mIconWidth / 2;
			int top = getMeasuredHeight() / 2 - (mTextBound.height() + mIconHeight) / 2;

			mIconRect.left = left;
			mIconRect.top = top;
			mIconRect.right = left + mIconWidth;
			mIconRect.bottom = top + mIconHeight;
		}

		/**
		 * 设置选项卡中图标的宽和高
		 * @param iconWidth
		 */
		public void setIconSize(int iconWidth, int iconHeight) {
			this.mIconWidth = iconWidth;
			this.mIconHeight = iconHeight;
			initTabDrawArea();
			invalidate();
		}

		@Override
		protected void onDraw(Canvas canvas) {
			// 绘制红点
			drawRedDot(canvas, mShowRedDot);

			// 绘制未读取条数
			drawUnreadCount(canvas, mUnreadCount);

			// 绘制tab原文本
			drawText(canvas, mTabColorNormal, 255);

			// 绘制渐变色的文本
			int alpha = (int) Math.ceil(255 * mAlphaPercent);
			drawText(canvas, mTabColorSelected, alpha);
			System.out.println("-------------mTabColorSelected: " + mTabColorSelected);

			if (mTabIconSelected == null) {	//只使用一张图片实现选项卡的普通和高亮两种状态
				// 绘制tab图标
				canvas.drawBitmap(mTabIconNormal, null, mIconRect, null);

				// 内存去准备mBitmap , setAlpha , 纯色 ，xfermode
				mGradientBitmap = createGradientBitmap(alpha, mTabColorSelected);

				// 绘制渐变色的图标
				canvas.drawBitmap(mGradientBitmap, 0, 0, null);

			} else {	//使用两张图片实现选项卡的普通和高亮两种状态
				if (alpha == 0) {
					canvas.drawBitmap(mTabIconNormal, null, mIconRect, null);
				} else {
					canvas.drawBitmap(mTabIconSelected, null, mIconRect, null);
				}
			}
		}

		private int dp2px(int dp) {
			return (int) (dp * getContext().getResources().getDisplayMetrics().density);
		}

		/**
		 * 绘制文本
		 *
		 * @param canvas
		 * @param alpha
		 */
		private void drawText(Canvas canvas, int color, int alpha) {
			mTextPaint.setColor(color);
			mTextPaint.setAlpha(alpha);
			int x = (getMeasuredWidth()  - mTextBound.width()) / 2;
			int y = mIconRect.bottom + mTextBound.height() + paddingBetweenTextAndIcon;
			canvas.drawText(mTabText, x, y, mTextPaint);
		}

		/** 设置图标和文本之间的间距 */
		public void setPaddingBetweenTextAndIcon(int padding) {
			this.paddingBetweenTextAndIcon = padding;
		}

		/**
		 * 在内存中绘制可变色的Icon
		 * @param alpha 透明度
		 * @param gradientColor 渐变色
		 * @return
		 */
		private Bitmap createGradientBitmap(int alpha, int gradientColor) {
			Canvas canvas = null;
			if (mGradientBitmap != null) {
				mGradientBitmap.recycle();
			}

			mGradientBitmap = Bitmap.createBitmap(getMeasuredWidth(),
					getMeasuredHeight(), Bitmap.Config.ARGB_8888);
			canvas = new Canvas(mGradientBitmap);
			mIconPaint = new Paint();
			mIconPaint.setColor(gradientColor);
			mIconPaint.setAntiAlias(true); // 去矩齿
			mIconPaint.setDither(true);
			mIconPaint.setAlpha(alpha); // 透明度
			canvas.drawRect(mIconRect, mIconPaint); // 画了一个矩形

			mIconPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

			mIconPaint.setAlpha(255);
			// 画了图标，图标与短形是重叠的，通过setXfermode()决定出来的效果
			canvas.drawBitmap(mTabIconNormal, null, mIconRect, mIconPaint);
			return mGradientBitmap;
		}

		/**
		 * 更新Tab显示的透明度
		 * @param alphaPercent 透明度 0 到 1
		 */
		public void updateTabAlpha(float alphaPercent) {
			// 如果使用了两张图片实现普通和高亮的效果，
			// 则禁用颜色渐变的功能；
			if (mTabIconSelected != null) {
				if (alphaPercent != 0 && alphaPercent != 1)
					return;
			}

			this.mAlphaPercent = alphaPercent;
			invalidate();
		}

		/**
		 * 设置Tab的选中状态
		 *
		 * @param selected true时显示为高亮, false为正常的显示状态
		 */
		public void setTabSelected(boolean selected) {
			updateTabAlpha(selected ? 1 : 0);
		}

		/**
		 * 设置要绘制的文本和图标。</br>
		 * 可以只设置一张默认的图标，控件会使用填充色对该图标进行染色得到选中时的高亮图标，
		 * 你也可以通过setTextAndIcons方法同时指定普通状态和选中状态的两个图标.
		 *
		 * @param text tab显示的文本
		 * @param icon tab显示的图标
		 */
		public void setTextAndIcon(String text, int icon) {
			this.mTabText = text;
			this.mTabIconNormal = BitmapFactory.decodeResource(getResources(), icon);
			mTextPaint.getTextBounds(mTabText, 0, mTabText.length(), mTextBound);
			invalidate();
		}

		/**
		 * 设置要绘制的文本和图标。</br>
		 *
		 * @param text tab显示的文本
		 * @param icon tab显示的图标
		 * @param iconSelected tab选中时显示的图标
		 */
		public void setTextAndIcon(String text, int icon, int iconSelected) {
			this.mTabText = text;
			this.mTabIconNormal = BitmapFactory.decodeResource(getResources(), icon);
			if (iconSelected > 0) {
				this.mTabIconSelected = BitmapFactory.decodeResource(getResources(), iconSelected);
			}
			mTextPaint.getTextBounds(mTabText, 0, mTabText.length(), mTextBound);
			invalidate();
		}

		/** 是否显示红点 */
		private boolean mShowRedDot = false;

		private Paint mRedDotPaint = new Paint();

		/**
		 * 绘制红点提示，传false还未隐藏红点
		 *
		 * @param canvas
		 * @param showRedDot 传true表示绘制红点，传false会清除之前绘制的红点
		 */
		private void drawRedDot(Canvas canvas, boolean showRedDot) {
			mRedDotPaint.setColor(showRedDot ? Color.RED : Color.TRANSPARENT);
			canvas.drawCircle(mIconRect.right + dp2px(3), mIconRect.top + dp2px(5), dp2px(5), mRedDotPaint);
		}

		/**
		 * 显示红点
		 *
		 * @param visible true表示显示
		 */
		private void setRedDotVisible(boolean visible) {
			mShowRedDot = visible;
			invalidate();
		}

		/**
		 * 显示选项卡上的红点，表示有新的消息
		 */
		public void showRedDot() {
			mShowRedDot = true;
			invalidate();
		}

		/**
		 * 隐藏选项卡上的红点
		 */
		public void hideRedDot() {
			mShowRedDot = false;
			invalidate();
		}

		private int mUnreadCount;

		public void setUnreadCount(int unreadCount) {
			this.mUnreadCount = unreadCount;
			invalidate();
		}

		private Paint mUnreadCountPaint = new Paint();
		private int mUnreadCountTextHeight;

		public void drawUnreadCount(Canvas canvas, int unreadCount) {
			boolean showUnreadCount = unreadCount > 0;
			mUnreadCountPaint.setColor(showUnreadCount? Color.WHITE : Color.TRANSPARENT);
			mRedDotPaint.setColor(showUnreadCount ? Color.RED : Color.TRANSPARENT);

			// 未读条数超过两位数时显示三个点...
			String text = unreadCount < 100 ? String.valueOf(unreadCount) : "...";
			int left = mIconRect.right + dp2px(8);
			int top = mIconRect.top + dp2px(9);

			canvas.drawCircle(left, top, dp2px(9), mRedDotPaint);
			canvas.drawText(text, left,  top +  mUnreadCountTextHeight / 2, mUnreadCountPaint);
		}
	}
}
